package zd.vrp.global;

import java.util.ArrayList;
import java.util.List;

public class GlobalInformation {
	public static int cityNum = 0;
	public static double maxX = -1;
	public static double minX = -1;
	public static double maxY = -1;
	public static double minY = -1;
	
	//city list
	public static List<City> cityList = new ArrayList();
	//remain unvisited city number
	public static int unvisitedCity;
	
	//route list
	public static List<Route> routeList = new ArrayList();	
	//city distance information
	public static double[] distance;
	//city rank information
	public static int[] ranks;
	
	//vehicle number
	public static int vehicleNum = 25;
	//vehicle capacity
	public static int vehicleCapacity = 200;
	//vehicle speed
	public static double vechielSpeed = 1;
	
	//neighbor area size
	public static int neighborSize = 20;
	
	
	//parameters for solomon insertion method 1
	public static double theta1 = 0.8;
	public static double theta2 = 0.1;
	public static double theta3 = 0.1;
	
	
	public static double getDistanceBetweenCities(City city1,City city2){
		return distance[city1.getId()*cityNum+city2.getId()];
	}
	
	
	//screen size
	public static int screenWidth = 640;
	public static int screenHeight = 600;
	public static int topMargin = 80;
	public static int leftMargin = 50;
	
	
	public static double getRouteLength(){
		double d = 0;
		for(Route route:routeList){
			for(int j=0;j<route.getCityList().size()-1;j++){
				City thisCity = route.getCityList().get(j);
				City nextCity = route.getCityList().get(j+1);
				d += distance[thisCity.getId()*cityNum+nextCity.getId()];
			}
		}
		return d;
	}
	
	public static double getRouteDuration(){
		double d = 0;
		for(Route route:routeList){
			City lastCity = route.getCityList().get(route.getLastCityIndex()-1);
			double td = lastCity.getFinishTime() + GlobalInformation.distance[lastCity.getId()]/GlobalInformation.vechielSpeed;
			/*if(td>d){
				d=td;
			}*/
			d += td;
		}
		return d;
	}
	
	//check feasibility of solution
	public static boolean checkTimeFeasibility(){
		for(Route route:routeList){
			for(int i=0;i<route.getCityList().size()-1;i++){
				City pCity = route.getCityList().get(i);
				City fCity = route.getCityList().get(i+1);
				double pStart = Math.max(pCity.getEtime(), pCity.getArrivalTime());
				if(pStart != pCity.getStartTime()){
					System.out.println("p start error");
					return false;
				}
				double pFinish = pStart+pCity.getServiceTime();
				if(pFinish != pCity.getFinishTime()){
					System.out.println("p finish error");
					return false;
				}
				double fArrival = pFinish + getDistanceBetweenCities(pCity, fCity)/vechielSpeed;
				if(fArrival != fCity.getArrivalTime()){
					System.out.println("f arrival error");
					return false;
				}
			}
			for(City city:route.getCityList()){
				if(city.getStartTime()<city.getEtime()||city.getArrivalTime()>city.getLtime()){
					System.out.println("violation city:"+city.getId()+"  startTime"+city.getStartTime()+"  etime:"+city.getEtime()+" ltime:"+city.getLtime());
					return false;
				}
			}
		}
		return true;
	}
	
	//check demand feasibility
	public static boolean checkDemandFeasibility(){
		for(Route route:routeList){
			double d=0;
			for(City city:route.getCityList()){
				d += city.getDemand();
			}
			if(d>vehicleCapacity){
				
				return false;
			}
		}
		return true;
	}
	
}
